"""
工作流实例扩展 API 路由
新增接口：从模板创建实例、复制实例、实例另存为模板
"""
import json
from datetime import datetime
from fastapi import APIRouter, Depends, HTTPException, Body, Query
from sqlalchemy.orm import Session
from typing import Optional, Dict, Any

from database import get_db
from schemas.workflow_schema import WorkflowInstanceDetailResponse, NodeExecutionInfo
from schemas.workflow_template_schema import (
    WorkflowTemplateDetailResponse,
    CreateTemplateFromInstanceRequest
)
from services.workflow_instance_service import WorkflowInstanceService
from services.workflow_service import WorkflowService
from services.workflow_engine import WorkflowEngine
from pydantic import BaseModel, Field

router = APIRouter(prefix="/api/workflow-instances", tags=["工作流实例扩展"])


# ============ 请求 Schema ============

class CreateInstanceFromTemplateRequest(BaseModel):
    """从模板创建实例请求"""
    template_id: int = Field(..., description="模板ID")
    instance_name: str = Field(..., description="实例名称", min_length=1, max_length=255)
    input_params: Optional[Dict[str, Any]] = Field(default_factory=dict, description="输入参数")
    trigger_type: str = Field("manual", description="触发类型（manual/cron）")
    trigger_user: Optional[str] = Field(None, description="触发人")
    cron_expression: Optional[str] = Field(None, description="Cron 表达式（可选）")
    cron_enabled: bool = Field(False, description="是否启用定时调度")
    auto_start: bool = Field(True, description="是否立即启动")
    schedule_type: str = Field("manual", description="调度类型（manual/scheduled/dependent/cron）")
    schedule_config: Optional[Dict[str, Any]] = Field(None, description="调度配置（依赖实例ID列表、定时时间等）")
    workflow_definition_snapshot: Optional[Dict[str, Any]] = Field(None, description="工作流定义快照（可选，用于覆盖模板定义）")
    created_by: Optional[str] = Field(None, description="创建人")


class DuplicateInstanceRequest(BaseModel):
    """复制实例请求"""
    new_instance_name: str = Field(..., description="新实例名称", min_length=1, max_length=255)
    input_params: Optional[Dict[str, Any]] = Field(None, description="输入参数（可覆盖源实例参数）")
    auto_start: bool = Field(False, description="是否立即启动")
    created_by: Optional[str] = Field(None, description="创建人")


class CreateInstanceResponse(BaseModel):
    """创建实例响应"""
    instance_id: int
    instance_name: str
    status: str
    message: str


# ============ 实例创建接口 ============

@router.post("/from-template", response_model=CreateInstanceResponse, summary="从模板创建实例")
def create_instance_from_template(
    request: CreateInstanceFromTemplateRequest,
    db: Session = Depends(get_db)
):
    """
    从工作流模板创建实例

    - **template_id**: 模板ID（必填）
    - **instance_name**: 实例名称（必填）
    - **input_params**: 输入参数（可选，可覆盖模板参数）
    - **auto_start**: 是否立即启动（默认 true）
    - **schedule_type**: 调度类型（manual/scheduled/dependent/cron）
    - **schedule_config**: 调度配置（依赖实例ID列表、定时时间等）
    """
    # 1. 验证调度配置
    is_valid, error_msg = WorkflowInstanceService.validate_schedule_config(
        db=db,
        schedule_type=request.schedule_type,
        schedule_config=request.schedule_config,
        instance_id=None  # 创建时还没有ID，循环检测会在后续处理
    )

    if not is_valid:
        raise HTTPException(status_code=400, detail=f"调度配置无效: {error_msg}")

    # 2. 创建实例
    success, error_msg, instance = WorkflowInstanceService.create_instance_from_template(
        db=db,
        template_id=request.template_id,
        instance_name=request.instance_name,
        input_params=request.input_params,
        trigger_type=request.trigger_type,
        trigger_user=request.trigger_user,
        cron_expression=request.cron_expression,
        cron_enabled=request.cron_enabled,
        workflow_definition_snapshot=request.workflow_definition_snapshot,
        auto_start=request.auto_start,
        schedule_type=request.schedule_type,
        schedule_config=request.schedule_config,
        created_by=request.created_by
    )

    if not success:
        raise HTTPException(status_code=400, detail=error_msg)

    # 3. 根据调度类型和状态生成消息
    schedule_type = instance.schedule_type if hasattr(instance, 'schedule_type') else 'manual'

    if instance.status == WorkflowEngine.STATUS_NOT_STARTED:
        message = "实例创建成功，状态为'未运行'，请点击'运行'按钮启动"
    elif schedule_type == 'scheduled':
        message = "实例创建成功，将在指定时间自动执行"
    elif schedule_type == 'dependent':
        message = "实例创建成功，等待依赖实例完成后自动执行"
    elif schedule_type == 'cron':
        message = "实例创建成功，将按CRON表达式定时执行"
    elif instance.status == WorkflowEngine.STATUS_INIT:
        message = "实例创建成功，已进入调度队列"
    else:
        message = "实例创建成功"

    # 4. 如果启用了定时调度，添加定时任务
    if request.cron_enabled and request.cron_expression:
        from services.scheduler_service import scheduler_service
        scheduler_service.add_instance_job(instance.id, request.cron_expression)
        message += "（定时任务已注册）"

    return CreateInstanceResponse(
        instance_id=instance.id,
        instance_name=instance.instance_name,
        status=instance.status,
        message=message
    )


@router.post("/{instance_id}/duplicate", response_model=CreateInstanceResponse, summary="复制实例")
def duplicate_instance(
    instance_id: int,
    request: DuplicateInstanceRequest,
    db: Session = Depends(get_db)
):
    """
    复制工作流实例

    基于已有实例创建新实例，可修改参数后执行

    - **new_instance_name**: 新实例名称（必填）
    - **input_params**: 输入参数（可选，覆盖源实例参数）
    - **auto_start**: 是否立即启动（默认 false）
    """
    # 1. 复制实例
    success, error_msg, new_instance = WorkflowInstanceService.duplicate_instance(
        db=db,
        source_instance_id=instance_id,
        new_instance_name=request.new_instance_name,
        input_params=request.input_params,
        created_by=request.created_by
    )

    if not success:
        raise HTTPException(status_code=400, detail=error_msg)

    # 2. 如果需要立即启动
    message = "实例复制成功"
    if request.auto_start:
        engine = WorkflowEngine(db)
        message = "实例复制成功并已启动"

    return CreateInstanceResponse(
        instance_id=new_instance.id,
        instance_name=new_instance.instance_name,
        status=new_instance.status,
        message=message
    )


@router.post("/{instance_id}/save-as-template", response_model=WorkflowTemplateDetailResponse, summary="实例另存为模板")
def save_instance_as_template(
    instance_id: int,
    request: CreateTemplateFromInstanceRequest,
    db: Session = Depends(get_db)
):
    """
    将工作流实例另存为模板

    - **template_name**: 新模板名称（必填）
    - **description**: 模板描述（可选）
    """
    success, error_msg, template = WorkflowInstanceService.save_instance_as_template(
        db=db,
        instance_id=instance_id,
        template_name=request.template_name,
        description=request.description,
        created_by=request.created_by
    )

    if not success:
        raise HTTPException(status_code=400, detail=error_msg)

    return WorkflowTemplateDetailResponse(
        id=template.id,
        name=template.name,
        description=template.description,
        workflow_definition=json.loads(template.workflow_definition),
        version=template.version,
        parent_version_id=template.parent_version_id,
        change_log=template.change_log,
        status=template.status,
        created_at=template.created_at,
        updated_at=template.updated_at,
        created_by=template.created_by
    )


# ============ 实例启动接口 ============

class StartInstanceResponse(BaseModel):
    """启动实例响应"""
    success: bool
    message: str
    instance_id: int
    status: str


@router.post("/{instance_id}/start", response_model=StartInstanceResponse, summary="启动未运行的实例")
def start_instance(
    instance_id: int,
    db: Session = Depends(get_db)
):
    """
    启动未运行的工作流实例

    将实例状态从"未运行"改为"初始化"，使其进入调度队列

    - **instance_id**: 实例ID
    """
    from models.workflow_instance import WorkflowInstance

    # 1. 查询实例
    instance = db.query(WorkflowInstance).filter(
        WorkflowInstance.id == instance_id,
        WorkflowInstance.deleted_at.is_(None)
    ).first()

    if not instance:
        raise HTTPException(status_code=404, detail="实例不存在")

    # 2. 验证状态
    if instance.status != WorkflowEngine.STATUS_NOT_STARTED:
        raise HTTPException(
            status_code=400,
            detail=f"只能启动'未运行'状态的实例，当前状态为：{instance.status}"
        )

    # 3. 修改状态为"初始化"
    instance.status = WorkflowEngine.STATUS_INIT
    db.commit()
    db.refresh(instance)

    return StartInstanceResponse(
        success=True,
        message="实例已启动，等待调度程序执行（约1分钟内）",
        instance_id=instance.id,
        status=instance.status
    )


# ============ 未运行实例查询接口 ============

class NotStartedInstanceListResponse(BaseModel):
    """未运行实例列表响应"""
    total: int
    items: list


@router.get("/not-started", response_model=NotStartedInstanceListResponse, summary="查询未运行的实例列表")
def get_not_started_instances(
    page: int = Query(1, ge=1, description="页码"),
    page_size: int = Query(20, ge=1, le=100, description="每页数量"),
    db: Session = Depends(get_db)
):
    """
    查询所有"未运行"状态的工作流实例

    这些实例已创建但尚未启动，需要用户手动点击"运行"按钮
    """
    from models.workflow_instance import WorkflowInstance
    from sqlalchemy import desc

    # 查询未运行的实例
    query = db.query(WorkflowInstance).filter(
        WorkflowInstance.status == WorkflowEngine.STATUS_NOT_STARTED,
        WorkflowInstance.deleted_at.is_(None)
    )

    total = query.count()

    # 按创建时间倒序
    instances = query.order_by(desc(WorkflowInstance.created_at)).offset(
        (page - 1) * page_size
    ).limit(page_size).all()

    items = [
        {
            "id": i.id,
            "instance_name": i.instance_name,
            "template_id": i.template_id,
            "template_name": i.template_name,
            "status": i.status,
            "trigger_type": i.trigger_type,
            "created_at": i.created_at.isoformat() if i.created_at else None,
            "created_by": i.created_by
        }
        for i in instances
    ]

    return NotStartedInstanceListResponse(total=total, items=items)


# ============ 定时调度管理接口 ============

class UpdateScheduleRequest(BaseModel):
    """更新调度配置请求"""
    cron_expression: Optional[str] = Field(None, description="Cron 表达式")
    cron_enabled: bool = Field(..., description="是否启用定时调度")


@router.put("/{instance_id}/schedule", summary="更新实例的定时调度")
def update_instance_schedule(
    instance_id: int,
    request: UpdateScheduleRequest,
    db: Session = Depends(get_db)
):
    """
    更新工作流实例的定时调度配置

    - **cron_expression**: Cron 表达式（可选）
    - **cron_enabled**: 是否启用定时调度
    """
    success, error_msg = WorkflowInstanceService.update_instance_schedule(
        db=db,
        instance_id=instance_id,
        cron_expression=request.cron_expression,
        cron_enabled=request.cron_enabled
    )

    if not success:
        raise HTTPException(status_code=400, detail=error_msg)

    # 管理定时任务
    from services.scheduler_service import scheduler_service
    if request.cron_enabled and request.cron_expression:
        # 启用定时调度，添加或更新任务
        scheduler_service.add_instance_job(instance_id, request.cron_expression)
        message = "定时调度已启用"
    else:
        # 禁用定时调度，删除任务
        scheduler_service.remove_instance_job(instance_id)
        message = "定时调度已禁用"

    return {"message": message}
